// Background service worker for handling notifications and alarms

// Initialize on install
chrome.runtime.onInstalled.addListener(async () => {
  // Initialize storage - defaults will be loaded by popup/newtab on first open
  const data = await chrome.storage.local.get(['initialized']);
  
  if (!data.initialized) {
    await chrome.storage.local.set({ initialized: true });
  }
  
  // Schedule all enabled reminders
  await scheduleAllReminders();
  
  // Fetch RSS feed on install
  await fetchRSSFeed();
  
  // Schedule periodic RSS updates (every 6 hours)
  chrome.alarms.create('rss-update', {
    delayInMinutes: 60,
    periodInMinutes: 360
  });
});

// Listen for storage changes to reschedule reminders
chrome.storage.onChanged.addListener(async (changes, areaName) => {
  if (areaName === 'local' && changes.reminders) {
    await scheduleAllReminders();
  }
});

// Schedule all enabled reminders
async function scheduleAllReminders() {
  // Clear all existing alarms
  const alarms = await chrome.alarms.getAll();
  alarms.forEach(alarm => {
    if (alarm.name.startsWith('reminder-')) {
      chrome.alarms.clear(alarm.name);
    }
  });

  const data = await chrome.storage.local.get(['reminders', 'settings']);
  const reminders = data.reminders || [];
  const settings = data.settings || {};

  reminders.forEach(reminder => {
    if (reminder.enabled) {
      scheduleReminder(reminder, settings);
    }
  });
}

// Schedule a single reminder
function scheduleReminder(reminder, settings) {
  const alarmName = `reminder-${reminder.id}`;
  
  // Clear existing alarm for this reminder
  chrome.alarms.clear(alarmName);

  if (reminder.timeOfDay) {
    // Time-based reminder (e.g., daily at specific time)
    const now = new Date();
    const [hours, minutes] = reminder.timeOfDay.split(':').map(Number);
    const scheduledTime = new Date();
    scheduledTime.setHours(hours, minutes, 0, 0);
    
    // If time has passed today, schedule for tomorrow
    if (scheduledTime <= now) {
      scheduledTime.setDate(scheduledTime.getDate() + 1);
    }
    
    chrome.alarms.create(alarmName, {
      when: scheduledTime.getTime()
    });
  } else {
    // Frequency-based reminder
    const delayInMinutes = reminder.frequency || 60;
    chrome.alarms.create(alarmName, {
      delayInMinutes: delayInMinutes,
      periodInMinutes: delayInMinutes
    });
  }
}

// Handle alarm triggers
chrome.alarms.onAlarm.addListener(async (alarm) => {
  if (alarm.name.startsWith('reminder-')) {
    const reminderId = alarm.name.replace('reminder-', '');
    await triggerReminder(reminderId);
  } else if (alarm.name === 'rss-update') {
    await fetchRSSFeed();
  }
});

// Trigger a reminder
async function triggerReminder(reminderId) {
  const data = await chrome.storage.local.get(['reminders', 'settings']);
  const reminders = data.reminders || [];
  const settings = data.settings || {};
  
  const reminder = reminders.find(r => r.id === reminderId);
  if (!reminder || !reminder.enabled) return;

  // Update last triggered time
  const updatedReminders = reminders.map(r => 
    r.id === reminderId ? { ...r, lastTriggered: Date.now() } : r
  );
  await chrome.storage.local.set({ reminders: updatedReminders });

  // Track reminder completion for gamification
  await trackReminderCompletion(reminder);

  // Play sound notification if enabled
  const soundType = settings.notificationSound || 'beep';
  if (soundType !== 'none') {
    playNotificationSound(soundType);
  }

  // Show notification if enabled
  if (settings.notificationsEnabled !== false) {
    chrome.notifications.create({
      type: 'basic',
      iconUrl: 'icons/icon48.png',
      title: reminder.title,
      message: reminder.description || `Time for: ${reminder.title}`,
      priority: 1
    });
  }

  // Update badge if enabled
  if (settings.badgeEnabled !== false) {
    const badgeData = await chrome.storage.local.get('badgeCount');
    const currentCount = badgeData.badgeCount || 0;
    await chrome.storage.local.set({ badgeCount: currentCount + 1 });
    chrome.action.setBadgeText({ text: String(currentCount + 1) });
    chrome.action.setBadgeBackgroundColor({ color: '#4CAF50' });
  }

  // Reschedule the reminder
  scheduleReminder(reminder, settings);
}

// Track reminder completion for gamification
async function trackReminderCompletion(reminder) {
  try {
    const gamificationData = await chrome.storage.local.get('gamification');
    const gamification = gamificationData.gamification || {
      stats: { hydrationCompleted: 0, remindersCompleted: 0 }
    };
    
    // Update stats
    const stats = gamification.stats || {};
    stats.remindersCompleted = (stats.remindersCompleted || 0) + 1;
    
    // Track specific categories
    if (reminder.category === 'Hydration') {
      stats.hydrationCompleted = (stats.hydrationCompleted || 0) + 1;
      
      // Update hydration goal progress
      const goals = await chrome.storage.local.get('userGoals');
      const hydrationGoals = (goals.userGoals || []).filter(g => 
        g.category === 'Hydration' && g.id === 'daily-hydration'
      );
      
      if (hydrationGoals.length > 0) {
        const goalProgress = gamification.goalProgress || {};
        const goalId = hydrationGoals[0].id;
        goalProgress[goalId] = (goalProgress[goalId] || 0) + 1;
        gamification.goalProgress = goalProgress;
      }
    }
    
    gamification.stats = stats;
    await chrome.storage.local.set({ gamification });
  } catch (error) {
    console.error('Error tracking reminder completion:', error);
  }
}

// Handle notification clicks
chrome.notifications.onClicked.addListener((notificationId) => {
  chrome.notifications.clear(notificationId);
  // Open dashboard
  chrome.tabs.create({ url: chrome.runtime.getURL('dashboard.html') });
});

// Handle extension icon click - open dashboard
chrome.action.onClicked.addListener(() => {
  chrome.tabs.create({ url: chrome.runtime.getURL('dashboard.html') });
});

// Clear badge when popup opens
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'clearBadge') {
    chrome.action.setBadgeText({ text: '' });
    chrome.storage.local.set({ badgeCount: 0 });
  } else if (request.action === 'reminderDue') {
    // Handle reminder becoming due
    handleReminderDue(request.reminder);
    sendResponse({ success: true });
  } else if (request.action === 'fetchRSS') {
    // Manually trigger RSS fetch
    fetchRSSFeed().then(() => {
      sendResponse({ success: true });
    }).catch((error) => {
      sendResponse({ success: false, error: error.message });
    });
    return true; // Keep channel open for async response
  }
  return true; // Keep channel open for async response
});

// Handle reminder becoming due (from popup timer)
async function handleReminderDue(reminder) {
  if (!reminder || !reminder.enabled) return;
  
  const settings = await chrome.storage.local.get('settings');
  const userSettings = settings.settings || {};
  
  // Play sound notification if enabled
  const soundType = userSettings.notificationSound || 'beep';
  if (soundType !== 'none') {
    playNotificationSound(soundType);
  }
  
  // Show notification if enabled
  if (userSettings.notificationsEnabled !== false) {
    chrome.notifications.create({
      type: 'basic',
      iconUrl: 'icons/icon48.png',
      title: reminder.title,
      message: reminder.description || `Time for: ${reminder.title}`,
      priority: 2,
      requireInteraction: false
    });
  }
  
  // Update badge if enabled
  if (userSettings.badgeEnabled !== false) {
    const badgeData = await chrome.storage.local.get('badgeCount');
    const currentCount = badgeData.badgeCount || 0;
    await chrome.storage.local.set({ badgeCount: currentCount + 1 });
    chrome.action.setBadgeText({ text: String(currentCount + 1) });
    chrome.action.setBadgeBackgroundColor({ color: '#4CAF50' });
  }
}

// Play notification sound by injecting script into active tab
async function playNotificationSound(soundType = 'beep') {
  try {
    // Get all tabs, filtering out chrome:// and extension pages
    const tabs = await chrome.tabs.query({});
    const injectableTabs = tabs.filter(tab => 
      tab.url && 
      !tab.url.startsWith('chrome://') && 
      !tab.url.startsWith('chrome-extension://') &&
      !tab.url.startsWith('edge://')
    );
    
    // Try to inject script into an available tab to play sound
    // We need at least one tab to have a page context for Web Audio API
    if (injectableTabs.length > 0) {
      const tab = injectableTabs[0];
      
      // Inject script to play sound
      await chrome.scripting.executeScript({
        target: { tabId: tab.id },
        func: (soundType) => {
          try {
            const audioContext = new (window.AudioContext || window.webkitAudioContext)();
            
            // Play sound function based on type
            const playSound = () => {
              const oscillator = audioContext.createOscillator();
              const gainNode = audioContext.createGain();
              
              oscillator.connect(gainNode);
              gainNode.connect(audioContext.destination);
              
              // Configure sound based on type
              switch(soundType) {
                case 'chime':
                  oscillator.frequency.value = 523.25; // C5
                  oscillator.type = 'sine';
                  gainNode.gain.setValueAtTime(0, audioContext.currentTime);
                  gainNode.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.01);
                  gainNode.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.15);
                  gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.3);
                  oscillator.start(audioContext.currentTime);
                  oscillator.stop(audioContext.currentTime + 0.3);
                  
                  // Play second note for chime
                  setTimeout(() => {
                    const osc2 = audioContext.createOscillator();
                    const gain2 = audioContext.createGain();
                    osc2.connect(gain2);
                    gain2.connect(audioContext.destination);
                    osc2.frequency.value = 659.25; // E5
                    osc2.type = 'sine';
                    gain2.gain.setValueAtTime(0, audioContext.currentTime);
                    gain2.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.01);
                    gain2.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.15);
                    gain2.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.3);
                    osc2.start(audioContext.currentTime);
                    osc2.stop(audioContext.currentTime + 0.3);
                  }, 200);
                  break;
                  
                case 'bell':
                  oscillator.frequency.value = 880; // A5
                  oscillator.type = 'sine';
                  gainNode.gain.setValueAtTime(0, audioContext.currentTime);
                  gainNode.gain.linearRampToValueAtTime(0.4, audioContext.currentTime + 0.01);
                  gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.5);
                  oscillator.start(audioContext.currentTime);
                  oscillator.stop(audioContext.currentTime + 0.5);
                  break;
                  
                case 'beep':
                default:
                  oscillator.frequency.value = 800;
                  oscillator.type = 'sine';
                  gainNode.gain.setValueAtTime(0, audioContext.currentTime);
                  gainNode.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.01);
                  gainNode.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.1);
                  gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.2);
                  oscillator.start(audioContext.currentTime);
                  oscillator.stop(audioContext.currentTime + 0.2);
                  
                  // Play second beep
                  setTimeout(() => {
                    const osc2 = audioContext.createOscillator();
                    const gain2 = audioContext.createGain();
                    osc2.connect(gain2);
                    gain2.connect(audioContext.destination);
                    osc2.frequency.value = 800;
                    osc2.type = 'sine';
                    gain2.gain.setValueAtTime(0, audioContext.currentTime);
                    gain2.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.01);
                    gain2.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.1);
                    gain2.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.2);
                    osc2.start(audioContext.currentTime);
                    osc2.stop(audioContext.currentTime + 0.2);
                  }, 250);
                  break;
              }
            };
            
            playSound();
          } catch (error) {
            // Silently fail - sound is optional
          }
        },
        args: [soundType]
      }).catch(() => {
        // If injection fails, that's okay - notification will still show
        // System notification sound will play anyway
      });
    }
  } catch (error) {
    // Silently fail - sound is optional, notification will still show
  }
}

// Periodically check reminders even when popup is closed
setInterval(async () => {
  const data = await chrome.storage.local.get(['reminders', 'settings']);
  const reminders = data.reminders || [];
  const settings = data.settings || {};
  
  const now = Date.now();
  const checkedReminders = await chrome.storage.local.get('checkedReminders');
  const lastChecked = checkedReminders.checkedReminders || {};
  
  reminders.forEach(reminder => {
    if (!reminder.enabled || !reminder.lastTriggered) return;
    
    const frequencyMs = reminder.frequency * 60 * 1000;
    const nextTriggerTime = reminder.lastTriggered + frequencyMs;
    const timeRemaining = nextTriggerTime - now;
    
    // Check if reminder just became due (within last 2 seconds)
    const reminderKey = reminder.id;
    const wasDue = lastChecked[reminderKey] || false;
    const isDue = timeRemaining <= 0;
    
    if (!wasDue && isDue) {
      // Reminder just became due
      handleReminderDue(reminder);
      lastChecked[reminderKey] = true;
    } else if (wasDue && !isDue) {
      // Reminder is no longer due (was reset)
      lastChecked[reminderKey] = false;
    }
  });
  
  // Save checked state
  await chrome.storage.local.set({ checkedReminders: lastChecked });
}, 2000); // Check every 2 seconds

// RSS Feed Functions
const RSS_FEED_URL = 'https://www.lifespan.io/feed/';

// Helper function to decode HTML entities (works in service workers)
function decodeHTML(text) {
  if (!text) return '';
  // Manual replacement of common HTML entities
  return text
    .replace(/&nbsp;/g, ' ')
    .replace(/&amp;/g, '&')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'")
    .replace(/&#x27;/g, "'")
    .replace(/&#8217;/g, "'")
    .replace(/&#8211;/g, '–')
    .replace(/&#8212;/g, '—')
    .replace(/&#8230;/g, '…')
    .replace(/&apos;/g, "'")
    .replace(/&#039;/g, "'")
    .replace(/&#x2F;/g, '/')
    .replace(/&#x60;/g, '`')
    .replace(/&#x3D;/g, '=');
}

async function fetchRSSFeed() {
  try {
    const response = await fetch(RSS_FEED_URL);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const xmlText = await response.text();
    const articles = parseRSSFeed(xmlText);
    
    // Store articles with timestamp
    await chrome.storage.local.set({
      rssArticles: articles,
      rssLastUpdate: Date.now()
    });
    
    console.log(`RSS feed updated: ${articles.length} articles`);
  } catch (error) {
    console.error('Error fetching RSS feed:', error);
    // Don't overwrite existing articles on error
  }
}

function parseRSSFeed(xmlText) {
  const articles = [];
  
  // Extract all <item> blocks using regex
  const itemRegex = /<item[^>]*>([\s\S]*?)<\/item>/gi;
  const items = xmlText.match(itemRegex);
  
  if (!items || items.length === 0) {
    console.error('No RSS items found');
    return articles;
  }
  
  items.forEach((itemXml, index) => {
    // Extract title
    const titleMatch = itemXml.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
    const title = titleMatch ? extractTextContent(titleMatch[1]) : '';
    
    // Extract link
    const linkMatch = itemXml.match(/<link[^>]*>([\s\S]*?)<\/link>/i);
    const link = linkMatch ? extractTextContent(linkMatch[1]).trim() : '';
    
    // Extract description
    const descMatch = itemXml.match(/<description[^>]*>([\s\S]*?)<\/description>/i);
    const description = descMatch ? extractTextContent(descMatch[1]) : '';
    
    // Extract pubDate
    const pubDateMatch = itemXml.match(/<pubDate[^>]*>([\s\S]*?)<\/pubDate>/i);
    const pubDate = pubDateMatch ? extractTextContent(pubDateMatch[1]).trim() : '';
    
    // Extract categories
    const categoryRegex = /<category[^>]*>([\s\S]*?)<\/category>/gi;
    const categoryMatches = itemXml.match(categoryRegex);
    const categories = categoryMatches 
      ? categoryMatches.map(match => {
          const catText = match.replace(/<\/?category[^>]*>/gi, '');
          return extractTextContent(catText).trim();
        }).filter(cat => cat.length > 0)
      : [];
    
    // Extract image URL from media:content
    let imageUrl = '';
    const mediaContentMatch = itemXml.match(/<media:content[^>]*url=["']([^"']+)["'][^>]*>/i) ||
                              itemXml.match(/<content[^>]*url=["']([^"']+)["'][^>]*>/i);
    if (mediaContentMatch) {
      imageUrl = mediaContentMatch[1];
    }
    
    // Also check enclosure tag
    if (!imageUrl) {
      const enclosureMatch = itemXml.match(/<enclosure[^>]*url=["']([^"']+)["'][^>]*type=["']([^"']+)["'][^>]*>/i);
      if (enclosureMatch && enclosureMatch[2]?.startsWith('image/')) {
        imageUrl = enclosureMatch[1];
      }
    }
    
    // Clean description (remove HTML tags and decode entities)
    const cleanDescription = decodeHTML(description)
      .replace(/<[^>]*>/g, '')
      .trim()
      .substring(0, 200); // Limit to 200 characters
    
    // Clean title (decode HTML entities)
    const cleanTitle = decodeHTML(title).trim();
    
    if (cleanTitle) {
      articles.push({
        id: `rss-${Date.now()}-${index}`,
        title: cleanTitle,
        link: link,
        description: cleanDescription,
        pubDate: pubDate,
        categories: categories,
        imageUrl: imageUrl,
        source: 'Lifespan.io',
        timestamp: Date.now()
      });
    }
  });
  
  return articles;
}

// Helper function to extract text content from XML tags
function extractTextContent(text) {
  if (!text) return '';
  // Remove CDATA wrapper if present
  text = text.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/gi, '$1');
  // Decode HTML entities
  return decodeHTML(text);
}

